﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web.Mvc;
using System.Web.Security;
using Coticula.Web.Models;
using Coticula.Web.Helpers;

namespace Coticula.Web.Controllers
{
    public class SolutionController : Controller
    {
        private readonly CoticulaDbContext _db = new CoticulaDbContext();

        private const int DefaultPageSize = 20;

        public PagedList<Results> GetPagedResults(int page, int take)
        {
            int skip = (page - 1) * take;
            var query =
                _db.Results.Include(r => r.Verdict).Include(r => r.Solution.Language).Include(r => r.Solution.Problem).
                    OrderByDescending(r => r.Id);
            int resultCount = query.Count();

            var results = query.Skip(skip).Take(take).ToList();

            return new PagedList<Results>()
            {
                Entities = results,
                HasMore = (skip + take < resultCount),
                HasPrevious = (skip > 0),
                CurrentPage = page
            };
        }

        //
        // GET: /Solution/
        // GET: /Solution/Index
        // GET: /Solution/Index/7
        // GET: /Solution/Index/7/20

        public ViewResult Index(int? page)
        {
            if (page == null) page = 1;
            const int pageSize = DefaultPageSize;

            ViewBag.Page = page;
            ViewBag.PageSize = pageSize;

            var pagedResultsSolution = this.GetPagedResults((int)page, pageSize);
            var resultsSolution = pagedResultsSolution.Entities;
            var results = from MembershipUser user in Membership.GetAllUsers()
                          join result in resultsSolution on user.ProviderUserKey equals result.Solution.UserId
                          select new Results(result, user);
            results = results.OrderByDescending(r => r.Id);

            ViewBag.HasPrevious = pagedResultsSolution.HasPrevious;
            ViewBag.HasMore = pagedResultsSolution.HasMore;
            ViewBag.CurrentPage = pagedResultsSolution.CurrentPage;

            return View(results);
        }

        //
        // GET: /Solution/Details/5
        [Authorize]
        public ActionResult Details(int id, string format)
        {
            //return User.Identity.IsAuthenticated /*&& User.IsInRole("Tester")*/;
            var resultWithSolution =
                _db.Results.Include(r => r.Solution.Language).Include(r => r.Solution.Problem).Include(r => r.Verdict).
                    Single(r => r.Id == id);
            var result = (from MembershipUser user in Membership.GetAllUsers()
                           where (int)user.ProviderUserKey == resultWithSolution.Solution.UserId
                           select new Results(resultWithSolution, user)).First();
            if ((int)result.User.ProviderUserKey != (int)Membership.GetUser(User.Identity.Name).ProviderUserKey && !User.IsInRole("Administrator"))
            {
                return View("AccessDenied");
            }
            if (result.TestsResults != null)
            {
                result.TestsResults = result.TestsResults.OrderBy(r => r.TestId).ToList();

            }
            return View(result);
        }

        //
        // GET: /Solution/Edit/5

        [Authorize(Roles = "Administrator")]
        public ActionResult Edit(int id)
        {
            var result = _db.Results.Find(id);
            ViewBag.VerdictId = new SelectList(_db.Verdicts, "Id", "Name", result.VerdictId);
            return View(result);
        }

        //
        // POST: /Solution/Edit/5

        [HttpPost]
        [Authorize(Roles = "Administrator")]
        public ActionResult Edit(Results result)
        {
            if (ModelState.IsValid)
            {
                _db.Entry(result).State = EntityState.Modified;
                _db.SaveChanges();
                return RedirectToAction("Index");
            }
            ViewBag.VerdictId = new SelectList(_db.Verdicts, "Id", "Name", result.VerdictId);
            return View(result);
        }

        //
        // GET: /Solution/Delete/5

        [Authorize(Roles = "Administrator")]
        public ActionResult Delete(int id)
        {
            var result = _db.Results.Find(id);
            return View(result);
        }

        //
        // POST: /Solution/Delete/5

        [HttpPost]
        [ActionName("Delete")]
        [Authorize(Roles = "Administrator")]
        public ActionResult DeleteConfirmed(int id)
        {
            var result = _db.Results.Find(id);
            _db.Results.Remove(result);
            _db.SaveChanges();
            return RedirectToAction("Index");
        }

        protected override void Dispose(bool disposing)
        {
            _db.Dispose();
            base.Dispose(disposing);
        }
    }
}
